// RealPlay Ltd  copyrights.
// This program is Open Source AsIs
// You may use it for all purposes, including commercial
// But!!!
// If you use any part of this code, you must state clearly
// both in your source file and in the Help|about of your program,
// that the origin program or code was built by RealPlay Ltd

// ***********************************************************************/
// *                                                                     */
// *        This unit ctrl the Z(Undo & Redo) Actions of "Paint" Program */
// *                                                                     */
// ***********************************************************************/

unit UPZAct;

interface

uses Classes, Graphics, SysUtils, ExtCtrls;

type

  TFifo = class(tstringlist)
  private
    fnu, last: integer;
    procedure setF(V: Tobject);
    function getF: Tobject;
    function getB: Tobject;
  public
    got: boolean;
    constructor Create(Nu: integer);
    destructor Destroy; override;
  end;

  TZItem = class(Tbitmap)
  public
    Tool: integer;
  end;

  TZFifo = class(TFifo)
  private
    fImage: TImage;
  public
    constructor Create(Nu: integer; NImage: TImage);
    procedure setF;
    procedure getF;
    procedure getB;
    procedure GetN; // Get Null operation ie for tool=line
  end;

implementation

uses UPMain, UPUtil;

// ZFifo  --------------------------

constructor TZFifo.Create(Nu: integer; NImage: TImage);
begin
  inherited Create(Nu);
  fImage := NImage;
end;

procedure TZFifo.getF;
var
  ZI: TZItem;
begin
  ZI := TZItem( inherited getF);
  if got then
    with FPaint do
    begin
      AssBMP(ZI, fImage);
    end;
end;

//
procedure TZFifo.getB;
var
  ZI: TZItem;
begin
  ZI := TZItem( inherited getB);
  if got then
    with FPaint do
    begin
      AssBMP(ZI, fImage);
    end;
end;

// ------------------------------------------------------------
procedure TZFifo.GetN; // Get Null operation ie for tool=line
begin
  inc(last);
  getF;
  // if got then inc(last);
end;

//
procedure TZFifo.setF;
var
  ZI: TZItem;
begin
  with FPaint do
  begin
    ZI := TZItem.Create;
    ZI.Assign(FWA.Im.Picture.Bitmap);
    ZI.Dormant;
    ZI.FreeImage;
  end;
  inherited setF(ZI);
end;

// Fifo ------------------------------------------------
constructor TFifo.Create(Nu: integer);
begin
  inherited Create;
  fnu := Nu;
  last := 0;
end;

//
destructor TFifo.Destroy;
var
  i: integer;
begin
  for i := 0 to count - 1 do
    objects[i].free;
  inherited Destroy;
end;

//
procedure TFifo.setF(V: Tobject);
var
  i: integer;
begin
  if last < count then
    for i := count - 1 downto last do
    begin
      objects[i].free;
      delete(i);
    end;
  addobject('', V);
  if count > fnu then
  begin
    objects[0].free;
    delete(0);
  end;
  last := count;
end;

function TFifo.getF: Tobject;
begin
  result := nil;
  got := false;
  if count = 0 then
    exit;
  if last > 1 then
  begin
    dec(last);
    got := true;
  end;
  result := objects[last - 1];
end;

function TFifo.getB: Tobject;
begin
  result := nil;
  got := false;
  if count = 0 then
    exit;
  if last < count then
  begin
    inc(last);
    got := true;
  end;
  result := objects[last - 1];
end;
// Fifo ----- END   -------------------------------------------

end.
